﻿using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;


namespace GaleSong
{
    /// <summary>
    ///     Base <see cref="IDialog" /> class for various implementations of <see cref="IDialog" />.
    /// </summary>
    public abstract class DialogBase : LocalizableDisplay, IDialog, IDataErrorInfo
    {
        #region Field

        private string _error = string.Empty;
        protected object _data;

        #endregion

        #region Constructor

        protected DialogBase(string name)
        {
            Name = name ?? GetType().Name.Replace("Dialog", string.Empty);
            AutoUpdate = true;
            IsOK = true;

            SaveCommand = new DelegateCommand(Save, CanSave);
            CancelCommand = new DelegateCommand(Cancel);
        }

        #endregion

        #region Property

        private string _icon;

        private bool _isNew;
        private ViewStrategy _viewStrategy;

        public string Icon
        {
            get { return _icon; }
            set
            {
                _icon = value;
                NotifyPropertyChanged(() => Icon);
            }
        }

        public virtual bool IsNew
        {
            get { return _isNew; }
            set
            {
                _isNew = value;
                NotifyPropertyChanged(() => IsNew);
            }
        }

        public virtual object Content
        {
            get { return ViewHelper.CreateView(this); }
        }

        public virtual bool Cacheable
        {
            // By default, the dialog is not caches able due, recreate it each time.
            get { return false; }
        }

        public ViewStrategy ViewStrategy
        {
            get { return _viewStrategy; }
            set
            {
                _viewStrategy = value;
                NotifyPropertyChanged(() => ViewStrategy, () => Content);
            }
        }

        public bool IsOK { get; protected set; }

        public bool HasError { get; protected set; }

        public bool HasSaved { get; protected set; }

        [Import(typeof(IWorkbench))]
        public IWorkbench Workbench { get; set; }

        #endregion

        #region ICommand

        public ICommand SaveCommand { get; protected set; }
        public ICommand CancelCommand { get; protected set; }

        #endregion

        #region Method

        public virtual T Data<T>()
        {
            return (T)_data;
        }

        protected virtual bool CanSave()
        {
            return true;
        }

        public virtual void Initialize()
        {
        }

        public virtual void Show()
        {
            IsOK = false;

            if (ViewStrategy == ViewStrategy.Wpf)
            {
                ((Window)Content).Show();
            }
            else
            {
                ((Form)Content).Show();
            }
        }

        public virtual void Show<T>(T t)
        {
            _data = t;
            Show();
        }

        public virtual void ShowDialog()
        {
            IsOK = false;

            if (ViewStrategy == ViewStrategy.Wpf)
            {
                ((Window)Content).ShowDialog();
            }
            else
            {
                ((Form)Content).ShowDialog();
            }
        }

        public virtual void ShowDialog<T>(T t)
        {
            _data = t;
            ShowDialog();
        }

        protected virtual void Cancel()
        {
            IsOK = false;
        }

        protected virtual void Save()
        {
            IsOK = true;
        }

        #endregion

        public string this[string columnName]
        {
            get
            {
                ValidateProperty(columnName, ref _error);
                return _error;
            }
        }

        [Browsable(false)]
        public string Error
        {
            get { return _error; }
        }

        protected virtual void ValidateProperty(string propertyName, ref string error)
        {
        }
    }
}